package com.klikmee.sms.core.base.communicator;

import java.text.MessageFormat;

import org.apache.log4j.Logger;

import com.klikmee.sms.core.base.CoreCacheDriver;
import com.klikmee.sms.core.base.communicator.mtel.MtelDeliveryReport2MessageResolverImpl;
import com.klikmee.sms.core.base.exceptions.DeliveryReportNotResolvedException;
import com.klikmee.sms.core.model.OutgoingMessage;

/**
 * Decorator for {@link MtelDeliveryReport2MessageResolverImpl} which queries
 * Core's outgoing cache first, and then if no message is found, delegates
 * search to database.
 * 
 * @author makcro
 * 
 */
public class DeliveryReport2MessageResolverCacheDecoratorImpl implements DeliveryReport2MessageResolver<OutgoingMessage> {

	private Logger							logger	= Logger.getLogger( DeliveryReport2MessageResolverCacheDecoratorImpl.class );

	/**
	 * Instance of decorated resolver
	 */
	private DeliveryReport2MessageResolver<OutgoingMessage>	decoratedResolver;

	/**
	 * Cache driver implementation used to read cache
	 */
	private CoreCacheDriver<DeliveryReport, OutgoingMessage>				cacheDriver;

	public DeliveryReport2MessageResolverCacheDecoratorImpl(DeliveryReport2MessageResolver<OutgoingMessage> deliveryReportResolver) {
		decoratedResolver = deliveryReportResolver;
	}

	/**
	 * Tries to resolve delivery report from cache. If resolution fails
	 * delegates it to decorated resolver.
	 */
	@Override
	public OutgoingMessage resolve(DeliveryReport deliveryReport) throws DeliveryReportNotResolvedException {

		logger.debug( MessageFormat.format( "Trying to resolve outgoing message with providers msg id [{0}]", deliveryReport.getProvidersMessageId() ) );
		OutgoingMessage outgoingMessage = cacheDriver.read( deliveryReport );

		if (outgoingMessage != null) {
			logger.info( MessageFormat.format( "Outgoing message with providers id [{0}] resolved from cache", outgoingMessage.getProvidersMesssageId() ) );
			return outgoingMessage;
		}

		// delegate to decorated resolver
		else {
			return decoratedResolver.resolve( deliveryReport );
		}

	}
	
	public void setCacheDriver(CoreCacheDriver<DeliveryReport, OutgoingMessage> cacheDriver) {
		this.cacheDriver = cacheDriver;
	}

}
